package com.document.service;

import com.document.entity.schema.*;
import freemarker.template.Configuration;
import freemarker.template.Template;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@Slf4j
@Service
@RequiredArgsConstructor
public class DocumentGenerator {

    private final Configuration freemarkerConfiguration;

    public String generateMarkdown(DatabaseSchema schema) {
        StringBuilder md = new StringBuilder();

        // 美化标题和元信息
        md.append("# 🗂 数据库文档\n\n");
        md.append("> **📅 生成时间**: ").append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))).append("  \n");
        md.append("> **🏷️ 数据库**: ").append(schema.getDatabaseName() != null ? schema.getDatabaseName() : "N/A").append("  \n");
        md.append("> **📊 表数量**: ").append(schema.getTables().size()).append("\n\n");

        if (schema == null || schema.getTables() == null || schema.getTables().isEmpty()) {
            md.append("> ⚠️ 没有找到数据库表信息\n");
            md.append("> \n");
            md.append("> 可能的原因：\n");
            md.append("> - SQL文件中没有包含CREATE TABLE语句\n");
            md.append("> - SQL文件格式不正确\n");
            md.append("> - 文件内容为空\n");
            return md.toString();
        }

        // 数据库概览 - 美化
        md.append("## 📋 数据库概览\n\n");
        md.append("| 项目 | 详情 |\n");
        md.append("|------|------|\n");
        md.append("| 数据库名称 | ").append(schema.getDatabaseName() != null ? schema.getDatabaseName() : "N/A").append(" |\n");
        md.append("| 数据库版本 | ").append(schema.getDatabaseVersion() != null ? schema.getDatabaseVersion() : "N/A").append(" |\n");
        md.append("| 表数量 | ").append(schema.getTables().size()).append(" |\n");
        md.append("| 总字段数 | ").append(schema.getTables().stream().mapToInt(t -> t.getColumns() != null ? t.getColumns().size() : 0).sum()).append(" |\n");
        md.append("| 外键关系 | ").append(schema.getForeignKeys() != null ? schema.getForeignKeys().size() : 0).append(" |\n\n");

        // 表清单 - 美化
        md.append("## 📊 表清单\n\n");
        for (Table table : schema.getTables()) {
            md.append("- **").append(table.getName()).append("**");
            if (table.getComment() != null && !table.getComment().isEmpty()) {
                md.append(" - ").append(escapeMarkdown(table.getComment()));
            }
            md.append("\n");
        }
        md.append("\n");

        // 表结构详情 - 美化
        md.append("## 🗃 表结构详情\n\n");

        for (Table table : schema.getTables()) {
            // 表标题美化
            md.append("### 📋 ").append(table.getName());
            if (table.getComment() != null && !table.getComment().isEmpty()) {
                md.append(" - ").append(escapeMarkdown(table.getComment()));
            }
            md.append("\n\n");

            // 表统计信息
            int columnCount = table.getColumns() != null ? table.getColumns().size() : 0;
            long pkCount = table.getColumns() != null ? table.getColumns().stream().filter(col -> Boolean.TRUE.equals(col.getPrimaryKey())).count() : 0;
            long fkCount = schema.getForeignKeys() != null ? schema.getForeignKeys().stream().filter(fk -> fk.getFkTableName().equals(table.getName())).count() : 0;

            md.append("**表统计**: ").append(columnCount).append(" 个字段 | ");
            md.append(pkCount).append(" 个主键 | ");
            md.append(fkCount).append(" 个外键\n\n");

            // 字段表格美化
            if (table.getColumns() != null && !table.getColumns().isEmpty()) {
                md.append("| 字段名 | 类型 | 长度 | 允许为空 | 默认值 | 主键 | 自增 | 注释 |\n");
                md.append("|:---|:---|:---:|:---:|:---|:---:|:---:|:---|\n");

                for (Column column : table.getColumns()) {
                    // 构建类型字符串
                    String typeStr = "`" + column.getType() + "`";
                    if (column.getSize() != null && column.getSize() > 0) {
                        typeStr += "(" + column.getSize();
                        if (column.getDecimalDigits() != null && column.getDecimalDigits() > 0) {
                            typeStr += "," + column.getDecimalDigits();
                        }
                        typeStr += ")";
                    }

                    // 构建长度字符串
                    String sizeStr = "";
                    if (column.getSize() != null && column.getSize() > 0) {
                        sizeStr = String.valueOf(column.getSize());
                        if (column.getDecimalDigits() != null && column.getDecimalDigits() > 0) {
                            sizeStr += "," + column.getDecimalDigits();
                        }
                    }

                    // 处理默认值
                    String defaultValue = column.getDefaultValue() != null ? escapeMarkdown(column.getDefaultValue()) : "";
                    if (!defaultValue.isEmpty()) {
                        defaultValue = "`" + defaultValue + "`";
                    }

                    // 处理注释
                    String comment = column.getComment() != null ? escapeMarkdown(column.getComment()) : "";

                    // 构建字段行 - 使用emoji和格式美化
                    String fieldName = column.getName();
                    if (Boolean.TRUE.equals(column.getPrimaryKey())) {
                        fieldName = "`" + fieldName + "` 🔑";
                    } else if (schema.getForeignKeys().stream().anyMatch(fk ->
                            fk.getFkTableName().equals(table.getName()) && fk.getFkColumnName().equals(column.getName()))) {
                        fieldName = "`" + fieldName + "` 🔗";
                    } else {
                        fieldName = "`" + fieldName + "`";
                    }

                    md.append("| ")
                            .append(fieldName).append(" | ")
                            .append(typeStr).append(" | ")
                            .append(sizeStr).append(" | ")
                            .append(Boolean.TRUE.equals(column.getNullable()) ? "✅" : "❌").append(" | ")
                            .append(defaultValue).append(" | ")
                            .append(Boolean.TRUE.equals(column.getPrimaryKey()) ? "✅" : "").append(" | ")
                            .append(Boolean.TRUE.equals(column.getAutoIncrement()) ? "✅" : "").append(" | ")
                            .append(comment).append(" |\n");
                }
                md.append("\n");
            }
        }

        // 外键关系 - 美化
        if (schema.getForeignKeys() != null && !schema.getForeignKeys().isEmpty()) {
            md.append("## 🔗 外键关系\n\n");
            md.append("| 外键表 | 外键字段 | 主键表 | 主键字段 |\n");
            md.append("|:---|:---|:---|:---|\n");

            for (ForeignKey fk : schema.getForeignKeys()) {
                md.append("| `").append(fk.getFkTableName()).append("` | ")
                        .append("`").append(fk.getFkColumnName()).append("` | ")
                        .append("`").append(fk.getPkTableName()).append("` | ")
                        .append("`").append(fk.getPkColumnName()).append("` |\n");
            }
            md.append("\n");
        }

        return md.toString();
    }

    /**
     * 转义 Markdown 中的特殊字符，处理换行符
     */
    private String escapeMarkdown(String text) {
        if (text == null) {
            return "";
        }

        // 替换换行符为空格，保持表格结构
        String escaped = text.replace("\n", " ").replace("\r", " ");

        // 转义其他 Markdown 特殊字符
        escaped = escaped.replace("|", "\\|")
                .replace("*", "\\*")
                .replace("_", "\\_")
                .replace("~", "\\~")
                .replace("`", "\\`")
                .replace("#", "\\#")
                .replace("+", "\\+")
                .replace("-", "\\-")
                .replace(".", "\\.")
                .replace("!", "\\!");

        return escaped.trim();
    }

    @PostConstruct
    public void init() {
        try {
            // 检查模板是否存在
            Template template = freemarkerConfiguration.getTemplate("database_template.ftl");
            log.info("FreeMarker模板加载成功");
        } catch (Exception e) {
            log.error("FreeMarker模板加载失败", e);
            // 创建美化模板
            createEnhancedTemplate();
        }
    }

    private void createEnhancedTemplate() {
        try {
            String templateContent =
                    "<!DOCTYPE html>\n" +
                            "<html lang=\"zh-CN\">\n" +
                            "<head>\n" +
                            "    <meta charset=\"UTF-8\">\n" +
                            "    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n" +
                            "    <title>数据库文档 - 专业版</title>\n" +
                            "    <style>\n" +
                            "        :root {\n" +
                            "            --primary: #1890ff;\n" +
                            "            --success: #52c41a;\n" +
                            "            --warning: #faad14;\n" +
                            "            --error: #ff4d4f;\n" +
                            "            --bg: #f8f9fa;\n" +
                            "            --card-bg: #ffffff;\n" +
                            "            --border: #e8e8e8;\n" +
                            "            --text: #262626;\n" +
                            "        }\n" +
                            "        \n" +
                            "        body {\n" +
                            "            font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, sans-serif;\n" +
                            "            background: var(--bg);\n" +
                            "            color: var(--text);\n" +
                            "            line-height: 1.6;\n" +
                            "            margin: 0;\n" +
                            "            padding: 20px;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .doc-header {\n" +
                            "            background: var(--card-bg);\n" +
                            "            padding: 24px;\n" +
                            "            border-radius: 8px;\n" +
                            "            box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n" +
                            "            margin-bottom: 24px;\n" +
                            "            border-left: 4px solid var(--primary);\n" +
                            "        }\n" +
                            "        \n" +
                            "        .doc-header h1 {\n" +
                            "            margin: 0 0 12px 0;\n" +
                            "            color: var(--primary);\n" +
                            "            font-size: 28px;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .doc-meta {\n" +
                            "            display: flex;\n" +
                            "            gap: 24px;\n" +
                            "            flex-wrap: wrap;\n" +
                            "            color: #666;\n" +
                            "            font-size: 14px;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .table-card {\n" +
                            "            background: var(--card-bg);\n" +
                            "            border-radius: 8px;\n" +
                            "            box-shadow: 0 2px 8px rgba(0,0,0,0.1);\n" +
                            "            margin-bottom: 24px;\n" +
                            "            overflow: hidden;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .table-header {\n" +
                            "            background: linear-gradient(135deg, #f0f7ff, #e6f7ff);\n" +
                            "            padding: 16px 20px;\n" +
                            "            border-bottom: 1px solid var(--border);\n" +
                            "        }\n" +
                            "        \n" +
                            "        .table-title {\n" +
                            "            margin: 0;\n" +
                            "            font-size: 18px;\n" +
                            "            display: flex;\n" +
                            "            align-items: center;\n" +
                            "            gap: 8px;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .table-comment {\n" +
                            "            color: #666;\n" +
                            "            font-size: 14px;\n" +
                            "            font-weight: normal;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .table-stats {\n" +
                            "            display: flex;\n" +
                            "            gap: 16px;\n" +
                            "            margin-top: 8px;\n" +
                            "            font-size: 13px;\n" +
                            "            color: #666;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .elegant-table {\n" +
                            "            width: 100%;\n" +
                            "            border-collapse: collapse;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .elegant-table th {\n" +
                            "            background: #fafafa;\n" +
                            "            padding: 12px 16px;\n" +
                            "            text-align: left;\n" +
                            "            font-weight: 600;\n" +
                            "            border-bottom: 2px solid var(--border);\n" +
                            "        }\n" +
                            "        \n" +
                            "        .elegant-table td {\n" +
                            "            padding: 12px 16px;\n" +
                            "            border-bottom: 1px solid var(--border);\n" +
                            "        }\n" +
                            "        \n" +
                            "        .elegant-table tr:hover {\n" +
                            "            background: #f0f7ff;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .elegant-table tr:nth-child(even) {\n" +
                            "            background: #fafafa;\n" +
                            "        }\n" +
                            "        \n" +
                            "        .pk-badge {\n" +
                            "            background: #fff2f0;\n" +
                            "            color: #cf1322;\n" +
                            "            padding: 2px 6px;\n" +
                            "            border-radius: 4px;\n" +
                            "            font-size: 12px;\n" +
                            "            border: 1px solid #ffccc7;\n" +
                            "        }\n" +
                            "    </style>\n" +
                            "</head>\n" +
                            "<body>\n" +
                            "    <div class=\"doc-header\">\n" +
                            "        <h1>🗂 数据库文档</h1>\n" +
                            "        <div class=\"doc-meta\">\n" +
                            "            <span>📅 生成时间: ${generateTime!''}</span>\n" +
                            "            <#if schema??>\n" +
                            "                <span>🏷️ 数据库: ${schema.databaseName!''}</span>\n" +
                            "                <span>📊 表数量: ${schema.tables?size}</span>\n" +
                            "            </#if>\n" +
                            "        </div>\n" +
                            "    </div>\n" +
                            "    \n" +
                            "    <#if schema??>\n" +
                            "        <#if schema.tables??>\n" +
                            "            <#list schema.tables as table>\n" +
                            "                <div class=\"table-card\">\n" +
                            "                    <div class=\"table-header\">\n" +
                            "                        <h2 class=\"table-title\">\n" +
                            "                            <span>📋</span>\n" +
                            "                            ${table.name!''}\n" +
                            "                            <#if table.comment??>\n" +
                            "                                <span class=\"table-comment\">- ${table.comment}</span>\n" +
                            "                            </#if>\n" +
                            "                        </h2>\n" +
                            "                        <div class=\"table-stats\">\n" +
                            "                            <span>${table.columns?size} 个字段</span>\n" +
                            "                            <#assign pkCount = table.columns?filter(col -> col.primaryKey?? && col.primaryKey)?size>\n" +
                            "                            <span>${pkCount} 个主键</span>\n" +
                            "                        </div>\n" +
                            "                    </div>\n" +
                            "                    \n" +
                            "                    <#if table.columns??>\n" +
                            "                        <table class=\"elegant-table\">\n" +
                            "                            <thead>\n" +
                            "                                <tr>\n" +
                            "                                    <th>字段名</th>\n" +
                            "                                    <th>类型</th>\n" +
                            "                                    <th>长度</th>\n" +
                            "                                    <th>允许为空</th>\n" +
                            "                                    <th>默认值</th>\n" +
                            "                                    <th>主键</th>\n" +
                            "                                    <th>自增</th>\n" +
                            "                                    <th>注释</th>\n" +
                            "                                </tr>\n" +
                            "                            </thead>\n" +
                            "                            <tbody>\n" +
                            "                                <#list table.columns as column>\n" +
                            "                                    <tr>\n" +
                            "                                        <td>\n" +
                            "                                            <#if column.primaryKey?? && column.primaryKey>\n" +
                            "                                                <span class=\"pk-badge\">${column.name!''} 🔑</span>\n" +
                            "                                            <#else>\n" +
                            "                                                ${column.name!''}\n" +
                            "                                            </#if>\n" +
                            "                                        </td>\n" +
                            "                                        <td><code>${column.type!''}</code></td>\n" +
                            "                                        <td>\n" +
                            "                                            <#if column.size??>\n" +
                            "                                                ${column.size}\n" +
                            "                                                <#if column.decimalDigits?? && column.decimalDigits &gt; 0>\n" +
                            "                                                    ,${column.decimalDigits}\n" +
                            "                                                </#if>\n" +
                            "                                            </#if>\n" +
                            "                                        </td>\n" +
                            "                                        <td>${(column.nullable!false)?string('✅','❌')}</td>\n" +
                            "                                        <td><code>${column.defaultValue!''}</code></td>\n" +
                            "                                        <td>${(column.primaryKey!false)?string('✅','')}</td>\n" +
                            "                                        <td>${(column.autoIncrement!false)?string('✅','')}</td>\n" +
                            "                                        <td>${column.comment!''}</td>\n" +
                            "                                    </tr>\n" +
                            "                                </#list>\n" +
                            "                            </tbody>\n" +
                            "                        </table>\n" +
                            "                    </#if>\n" +
                            "                </div>\n" +
                            "            </#list>\n" +
                            "        </#if>\n" +
                            "    </#if>\n" +
                            "</body>\n" +
                            "</html>";

            String templatesDir = "src/main/resources/templates";
            File dir = new File(templatesDir);
            if (!dir.exists()) {
                boolean created = dir.mkdirs();
                log.info("创建模板目录: {}, 结果: {}", dir.getAbsolutePath(), created);
            }

            File templateFile = new File(dir, "database_template.ftl");
            Files.write(templateFile.toPath(), templateContent.getBytes(StandardCharsets.UTF_8));
            log.info("创建美化FreeMarker模板成功: {}", templateFile.getAbsolutePath());

        } catch (Exception e) {
            log.error("创建美化模板失败", e);
        }
    }

    public String generateHtml(DatabaseSchema schema) {
        try {
            Map<String, Object> model = new HashMap<>();
            model.put("schema", schema);
            model.put("generateTime", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

            Template template = freemarkerConfiguration.getTemplate("database_template.ftl");
            return FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
        } catch (Exception e) {
            log.error("生成HTML文档失败", e);
            return generateFallbackHtml(schema);
        }
    }

    private String generateFallbackHtml(DatabaseSchema schema) {
        // 使用新的美化模板作为fallback
        return generateHtml(schema);
    }
}